//
// Description: 连接炸鸡店
// Created by Loading on 2021/6/27.
//

// 大栗在一个拥有n个城市的国家，它由n-1条双向道路连接，使得从一个城市可以到任意另一个城市，每一条道路的长度为1。
// 这个国家有2k家炸鸡店，坐落在不同的城市。
// 最近，大栗打算将这2k家炸鸡店两两配对，每一家炸鸡店有着唯一的搭档炸鸡店。对于每对炸鸡店，可以计算出他们之间的最短距离。
// 出于某种目的，大栗希望这k对炸鸡店两两最短距离的总和最大。
// 请帮助大栗找到最大总距离。

// Input
// 输入的第一行包括两个整数n和k（2<=n<=200000,1<=k<=n/2）分别代表城市的数量和炸鸡店的对数。这些城市被按照1到n命名。
// 第二行包括2k个不同的整数 u1 u2 … u2k(1<=ui<=n) 代表炸鸡店所坐落的城市。
// 接下来n-1行，每行两个整数xj和yj（1<=xj,yj<=n)
// 表示第j条道路连接城市xj和yj。它们所有都是双向道路。你可以从一个城市借助这些道路移动到任意另一城市。
//
// Output
// 输出将炸鸡店分成k对后，最大可能的两两距离的总和。

// Examples
//
// Input
// 7 2
// 1 5 6 7
// 1 2
// 2 3
// 2 4
// 2 5
// 4 6
// 4 7
//
// Output
// 6

// Input
// 9 3
// 2 3 4 5 8 9
// 1 2
// 1 3
// 2 4
// 2 5
// 2 6
// 4 7
// 7 9
// 6 8
//
// Output
// 9

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

LL res = 0;
int k;
//某条边的一侧（内部）的炸鸡店数量
vector<LL> inner_sum(200001);
//边集合
vector<vector<int>> g(200001);

/* 遍历每一条边，边两侧的 较少的 炸鸡店数量决定这条边的贡献值，将每条边的贡献值累加 */
void dfs(int u, int pre) {
    //遍历
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        if (v == pre) {
            continue;
        }
        //遍历这条边的另一个端点
        dfs(v, u);
        //另一个端点那一侧的炸鸡店数量累加到本端点
        inner_sum[u] += inner_sum[v];
        //边两侧（内侧，外侧）的炸鸡店数量，取小者
        res += min(inner_sum[v], k - inner_sum[v]);
    }
}

int main() {
    int n;
    int start_point = 0;
    cin >> n >> k;
    k <<= 1;
    for (int i = 0; i < k; ++i) {
        int temp;
        cin >> temp;
        if (start_point == 0) {
            start_point = temp;
        }
        inner_sum[temp]++;
    }

    for (int i = 1; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        //双向
        g[x].emplace_back(y);
        g[y].emplace_back(x);
    }

    //首次遍历，pre 传入一个非炸鸡店的随机值
    dfs(start_point, 0);
    cout << res << endl;
}